package com.lhn.spring5.testdemo;

import com.lhn.spring5.*;
import org.junit.Test;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.*;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 〈一句话功能简述>
 * 〈测试spring5〉
 *
 * @Author 17505
 * @Create 2021/12/23
 * @Since 1.0.0
 */
public class TestSpring5 {

    @Test
    public void test1() {
        // 1.加载spring 的配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    //    2.获取配置文件的对象
        User user = context.getBean("user", User.class);
        System.out.println(user);
        user.add();
    }

    @Test
    public void test2() {
        // 1.加载spring 的配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        //    2.获取配置文件的对象
        Book book = context.getBean("book", Book.class);
        System.out.println(book);
    }

    @Test
    public void test22() {
        // 1.加载spring 的配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        //    2.获取配置文件的对象
        Book book = context.getBean("book1", Book.class);
        System.out.println(book);
    }

    @Test
    public void test4() {
        // 1.加载spring 的配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        //    2.获取配置文件的对象
        Order order = context.getBean("order", Order.class);
        System.out.println(order);
    }

    @Test
    public void test5() {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        BeanFactory container = bingViaCode(beanFactory);
        Order order = container.getBean("order", Order.class);
        System.out.println(order);
    }

    public static BeanFactory bingViaCode(BeanDefinitionRegistry registry) {
        //******************************** 业务对象的构建管理 *************************************
        // 相当于就是一个对象实例
        AbstractBeanDefinition book = new RootBeanDefinition(Book.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
        AbstractBeanDefinition emp = new RootBeanDefinition(Emp.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
        AbstractBeanDefinition dep = new RootBeanDefinition(Dep.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
        AbstractBeanDefinition order = new RootBeanDefinition(Order.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);

         //将 bean 注入到容器中
        registry.registerBeanDefinition("book", book);
        registry.registerBeanDefinition("emp", emp);
        registry.registerBeanDefinition("dep", dep);
        registry.registerBeanDefinition("order", order);

        //******************************** 业务对象之间的依赖绑定 *************************************
        // 指定英依赖关系
        // 1. 可以通过构造器的方式注入
        ConstructorArgumentValues bookArgumentValues = new ConstructorArgumentValues();
        bookArgumentValues.addIndexedArgumentValue(0, "测试");
        bookArgumentValues.addIndexedArgumentValue(1, "李浩宁");
        book.setConstructorArgumentValues(bookArgumentValues);

        //ConstructorArgumentValues argumentValues = new ConstructorArgumentValues();
        //argumentValues.addIndexedArgumentValue(0, book);
        //order.setConstructorArgumentValues(argumentValues);

        // 2. 通过setter 的方式注入
        MutablePropertyValues propertyValues = new MutablePropertyValues();
        propertyValues.addPropertyValue(new PropertyValue("book", book));
        order.setPropertyValues(propertyValues);
        return (BeanFactory) registry;
    }

    @Test
    public void test6() {
        DefaultListableBeanFactory beanRegistry = new DefaultListableBeanFactory();
        BeanFactory beanFactory = bindViaXMLFile(beanRegistry);
        User username = beanFactory.getBean("user", User.class);

        System.out.println(username);
    }

    public static BeanFactory bindViaXMLFile(BeanDefinitionRegistry registry) {
        XmlBeanDefinitionReader  reader = new XmlBeanDefinitionReader(registry);
        reader.loadBeanDefinitions("classpath:/bean1.xml");
        return (BeanFactory) registry;
    }

    @Test
    public void test7() {
        ApplicationContext appContext = new ClassPathXmlApplicationContext("bean1.xml");
        Order order = appContext.getBean("order", Order.class);
        System.out.println(order);
    }
}